home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume11 / graphedit / part04 < prev    next >
Encoding:
Internet Message Format  |  1987-10-05  |  23.7 KB

  1. Subject:  v11i100:  Graphics editor for Suns, Part04/06
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rs@uunet.UU.NET
  5.  
  6. Submitted-by: steinmetz!sbcs!nyfca1!chan (Douglas Chan)
  7. Posting-number: Volume 11, Issue 100
  8. Archive-name: graphedit/part04
  9.  
  10. # This is a shell archive.  Remove anything before this line,
  11. # then unpack it by saving it in a file and typing "sh file".
  12. #
  13. # Contents:  core.c
  14.  
  15. echo x - core.c
  16. sed 's/^@//' > "core.c" <<'@//E*O*F core.c//'
  17.  
  18. static char SccsId[] = "@(#)core.c    1.2 6/8/87 Copyright 1987 SBCS-chan";
  19.  
  20. /*****************************************************************************
  21.  
  22.           (c) Copyright 1987 
  23.  
  24.           Lap-Tak Chan
  25.           Computer Science Department
  26.           State University of New York at Stony Brook
  27.           Stony Brook, NY 11794
  28.  
  29.     This software and its documentation may be used, copied, and
  30.   distributed, provided that this legend appear in all copies and
  31.   that it is not copied or distributed for a profit.
  32.  
  33.   No representations is made about the suitability of this software
  34.   for any purpose.  It is provided "as is" with no support and no
  35.   express or implied warranty.
  36.  
  37. *****************************************************************************/
  38.  
  39. /*****************************************************************************
  40.  
  41.                         SunCore Interface
  42.                         =================
  43.  
  44.     This file contains a package of routines used by graphedit as interface
  45.   to SunCore, which is used to maintain the display on the view surface and
  46.   to obtain mouse input from the view surface.
  47.  
  48. *****************************************************************************/
  49.  
  50. #include <usercore.h>
  51. #include <math.h>
  52. #include <stdio.h>
  53. #include "display.h"
  54. #include "suntool/sunview.h"
  55. #include "suntool/panel.h"
  56.  
  57. /* something from demolib.h */
  58. struct    vwsurf    *get_view_surface(/* (struct vwsurf *), argv */);
  59. struct    vwsurf    *get_surface(/* (struct vwsurf *), argv */);
  60. static    struct    vwsurf    Core_vwsurf;
  61. struct    vwsurf    *our_surface = &Core_vwsurf; /* our view surface */
  62.  
  63. /* pixrect device handlers */
  64. static int cg1dd();
  65. static int gp1dd();
  66. static int cg2dd();
  67. static int cg4dd(); /* only on Sun 3.2 and latter */
  68. static int cgpixwindd();
  69. static int pixwindd();
  70. static int gp1pixwindd();
  71.  
  72. #define MAPSIZE        256
  73. #define GE_TMPSEG 100000
  74.  
  75. /* The following two level mapping of colors can actually be reduced to
  76.    one level */
  77. /* entries in colormap used */
  78. static int colortable[] = {   0,  1,  20,  40, 63 , 85, 105,
  79.                 127, 147, 167, 191, 253, 254, 255 };
  80.  
  81. /* mapping between graphedit colors from 0-11 to colors in colortable */
  82. static int clrmap[] =
  83. { 1,2,3,4,5,6,7,8,9,10,11,13};
  84.  
  85. /* color table values for b/w screens */
  86. static float redlist[MAPSIZE], grnlist[MAPSIZE], blulist[MAPSIZE];
  87. /*  1     2     3     4     5     6     7     8    9    10    11   12 */
  88. static float redtex[] =
  89. {0.,.7334,.7922,.6667,.7765,.6589,.6589,.2667,.5334,.0314,.0235,.0157,0.,.0};
  90. static float grntex[] =
  91. {0.,.5334,.1922,.5334,.0667,.1922,.0667,.5334,.5334,.0667,.0667,.0667,0.,.2667 };
  92. static float blutex[] =
  93. {0.,.4001,.0000,.4001,.4001,.0000,.4001,.4001,.4001,.4001,.4001,.4001,0.,.3882};
  94.  
  95. /* color table values for color screens */
  96. static float credtex[]=
  97. {1.,.95,.9,.8,.75,.7,.6,.5,.4,.3,.2,.1,1.,0.};
  98. static float cgrntex[]=
  99. {1.,.95,.9,.8,.75,.7,.6,.5,.4,.3,.2,.1,1.,0.};
  100. static float cblutex[]=
  101. {1.,.95,.9,.8,.75,.7,.6,.5,.4,.3,.2,.1,1.,0.};
  102.  
  103. /*****************************************************************************
  104.  
  105.     set_up_core will create the view surface, initialize the input devices,
  106.   and setup the color table.
  107.  
  108. *****************************************************************************/
  109.  
  110. set_up_core(argv)
  111. char *argv[];
  112. {
  113.     int colorflag,i;
  114.     float white=1.0;
  115.     static char default_cood[]="301,0,851,650,512,836,64,64,0";
  116.     static char *ptrs[]={default_cood, (char *)0};
  117.  
  118.     /* start up SunCore */
  119.     if ( initialize_core(DYNAMICC, SYNCHRONOUS, TWOD)) exit(0);
  120.  
  121.     /* get what device the view surface will be created on */
  122.     get_view_surface(our_surface,argv);
  123.  
  124.     /* create a new window if view surface will be created in
  125.        suntools */
  126.     if ( (our_surface->dd == pixwindd) ||
  127.          (our_surface->dd == cgpixwindd) ||
  128.          (our_surface->dd == gp1pixwindd) ) {
  129.  
  130.       our_surface->flags=1;
  131.     }
  132.  
  133.     /* actually create the view surface */
  134.     our_surface->ptr = ptrs;
  135.     our_surface->cmapsize = MAPSIZE;
  136.     our_surface->cmapname[0] = '\0';
  137.     if (initialize_view_surface( our_surface, FALSE)) exit(0);
  138.  
  139.     /* initailize the input devices */
  140.     initialize_device( BUTTON, 1);
  141.     initialize_device( BUTTON, 2);
  142.     initialize_device( BUTTON, 3);
  143.     initialize_device( LOCATOR, 1);
  144.     initialize_device( PICK, 1);
  145.     set_echo_position( LOCATOR, 1, 0., 0.);
  146.     set_echo_surface( LOCATOR, 1, our_surface);
  147.     set_echo_surface( PICK, 1, our_surface);
  148.     set_pick(1,0.01);
  149.     set_echo( PICK, 1,1);
  150.  
  151.     /* initailize view surface */
  152.     set_window(0.,GE_WIN_X,0.,GE_WIN_Y);
  153.     set_viewport_2( 0.,1.,0., .75);    /* init viewing transform */
  154.     set_window_clipping(FALSE);
  155.     set_output_clipping(TRUE);
  156.     select_view_surface(our_surface);
  157.     set_image_transformation_type(XFORM2);
  158.     set_primitive_attributes( &PRIMATTS);
  159.     set_charprecision(CHARACTER);
  160.  
  161.     /* check whether view surface is on color device */
  162.     if((our_surface->dd == cg1dd) || (our_surface->dd == cgpixwindd) ||
  163.        (our_surface->dd == cg2dd) || (our_surface->dd == gp1dd)      ||
  164.        (our_surface->dd == cg4dd) || (our_surface->dd == gp1pixwindd))
  165.     colorflag=TRUE;
  166.     else
  167.     colorflag=FALSE;
  168.  
  169.     if(!colorflag) {
  170.         /* colormap for b/w device */
  171.         for (i=0;i<14;i++) {
  172.             redlist[colortable[i]]=redtex[i];
  173.             grnlist[colortable[i]]=grntex[i];
  174.             blulist[colortable[i]]=blutex[i];
  175.         }
  176.      }
  177.      else {
  178.         /* colormap for color device */
  179.         for (i=0;i<14;i++) {
  180.             redlist[colortable[i]]=credtex[i];
  181.             grnlist[colortable[i]]=cgrntex[i];
  182.             blulist[colortable[i]]=cblutex[i];
  183.          }
  184.         set_line_index(colortable[13]);
  185.         set_text_index(colortable[13]);
  186.       } /* if */
  187.  
  188.     /* setup the color map */
  189.     define_color_indices(our_surface,0,MAPSIZE-1,redlist,grnlist,blulist);
  190.  
  191.     /* create the crosshair used by ge_locator */
  192.     ge_crosshair();
  193.  
  194. } /* set_up_core */
  195.  
  196. /*****************************************************************************
  197.  
  198.     ge_crosshair will create the crosshair used by ge_locator.
  199.  
  200. *****************************************************************************/
  201.  
  202. #define CROSSHAIRSZ 2.5    /* size of crosshair */
  203.  
  204. ge_crosshair()
  205. {
  206.  
  207.   create_retained_segment(GE_CROSSHAIR);
  208.   set_segment_visibility(GE_CROSSHAIR,0);
  209.   move_abs_2(0., -CROSSHAIRSZ);
  210.   line_abs_2(0., CROSSHAIRSZ);
  211.   move_abs_2(-CROSSHAIRSZ, 0.);
  212.   line_abs_2(CROSSHAIRSZ, 0.);
  213.   close_retained_segment();
  214.  
  215. } /* ge_crosshair */
  216.  
  217. /*****************************************************************************
  218.  
  219.     do_exit will terminate the SunCore view surface.
  220.  
  221. *****************************************************************************/
  222.  
  223. do_exit()
  224. {
  225.    terminate_device( LOCATOR, 1);
  226.    deselect_view_surface(our_surface);
  227.    terminate_view_surface(our_surface);
  228.    terminate_core();
  229. } /* do_exit */
  230.  
  231. /*****************************************************************************
  232.  
  233.     ge_locator will read the mouse input within the view surface.  It 
  234.   behaves differently according to echo.
  235.  
  236.   Input
  237.     echo - if negative, read the current status of the mouse and
  238.            return immediately
  239.            otherwise, return the status of the mouse when any of the
  240.            buttons is hit
  241.            The mouse input will be echoed according to the value
  242.            of abs(echo) as how the locator in Suncore is echoed:
  243.              0 - no echo
  244.              1 - pointing finger
  245.              2 - line connecting from (x,y) to mouse location
  246.              3 - line connecting from (x,y) to x coordinate of mouse
  247.              4 - line connecting from (x,y) to y coordinate of mouse
  248.              5 - line connecting from (x,y) to x or y coordinate of mouse,
  249.                  whichever is further
  250.              6 - a box with (x,y) as one corner and mouse location the other
  251.                  corner
  252.  
  253.     x,y - world coordinate used by echo
  254.  
  255.   Output
  256.     butnum - number of button hit, 0 if no button was hit
  257.     x,y - world coordinate of mouse location
  258.  
  259. *****************************************************************************/
  260.  
  261. ge_locator(echo, butnum, x, y)
  262. int *butnum, echo;
  263. float *x, *y;
  264. {
  265.   float nx, ny;
  266.   int wait_int; /* how long (in ms) to wait */
  267.  
  268.   /* decide how long to wait */
  269.   if ( echo<0 ) {
  270.     echo = - echo;
  271.     wait_int=20;
  272.   }
  273.   else wait_int=100000000;
  274.  
  275.   /* set the echo reference position */
  276.   if ( echo > 1 ) {
  277.     map_world_to_ndc_2( *x, *y, &nx, &ny );
  278.     set_echo_position(LOCATOR, 1, nx, ny);
  279.   }
  280.  
  281.   if ( (echo == 1) && (wait_int > 1000) ) {
  282.  
  283.     /* put cross hair at location read because the location may not be the
  284.        position of the pointing finger */
  285.     set_echo(LOCATOR, 1, 0);
  286.     await_any_button_get_locator_2(200,1,butnum, &nx, &ny);
  287.     set_segment_image_transformation_2(GE_CROSSHAIR,1.,1.,0.,nx,ny);
  288.     set_segment_visibility(GE_CROSSHAIR,1);
  289.     while ( !(*butnum) ) {
  290.       await_any_button_get_locator_2(200,1,butnum, &nx, &ny);
  291.       set_segment_image_transformation_2(GE_CROSSHAIR,1.,1.,0.,nx,ny);
  292.     } /* while */
  293.     set_segment_visibility(GE_CROSSHAIR,0);
  294.  
  295.   }
  296.   else {
  297.     /* specify the echo and read locator input */
  298.     set_echo(LOCATOR, 1, echo);
  299.     await_any_button_get_locator_2(wait_int,1, butnum, &nx, &ny);
  300.   }
  301.  
  302.   /* map normal device coordinate back to world coordinate */
  303.   map_ndc_to_world_2(nx, ny, x, y);
  304.  
  305. } /* ge_locator */
  306.  
  307. /*****************************************************************************
  308.  
  309.     ge_tmp_new is used to create a temporary segment to echo a number of
  310.   lines drawn.
  311.  
  312.   Input
  313.     x,y - world coordinate to start at
  314.     attr - attributes of current segment
  315.  
  316. *****************************************************************************/
  317.  
  318. ge_tmp_new(x,y,attr)
  319. float x,y;
  320. struct attr attr;
  321. {
  322.   /* set attributes */
  323.   set_linestyle(attr.linestyle);
  324.   set_linewidth((float)attr.linewidth/5.);
  325.  
  326.   /* create temporary segment */
  327.   create_retained_segment(GE_TMPSEG);
  328.  
  329.   /* move to starting point */
  330.   move_abs_2(x,y);
  331.  
  332. } /* ge_tmp_new */
  333.  
  334. /*****************************************************************************
  335.  
  336.     ge_tmp_line is used to continue echo of a number of lines.
  337.  
  338.     Input
  339.       x,y - world coordinate to draw a line to
  340.  
  341. *****************************************************************************/
  342.  
  343. ge_tmp_line(x,y)
  344. float x,y;
  345. {
  346.  
  347.   line_abs_2(x,y);
  348.  
  349. } /* ge_tmp_line */
  350.  
  351. /*****************************************************************************
  352.  
  353.     ge_tmp_delete will delete the temporary segment created.
  354.  
  355. *****************************************************************************/
  356.  
  357. ge_tmp_delete()
  358. {
  359.  
  360.   close_retained_segment(GE_TMPSEG);
  361.   delete_retained_segment(GE_TMPSEG);
  362.  
  363. } /* ge_tmp_delete */
  364.  
  365. /*****************************************************************************
  366.  
  367.     ge_flush will flush all previous mouse input.
  368.  
  369. *****************************************************************************/
  370.  
  371. ge_flush()
  372. {
  373.   int butnum;
  374.   float x,y;
  375.  
  376.   do {
  377.     await_any_button_get_locator_2(0,1, &butnum, &x, &y);
  378.   } while ( butnum );
  379.  
  380. } /* ge_flush */
  381.  
  382. /*****************************************************************************
  383.  
  384.     ge_pick is used to pick a segment.  It will flush previous input and
  385.   wait for the user to pick a segment.
  386.  
  387.   Output
  388.     Return number of segment picked.
  389.  
  390. *****************************************************************************/
  391.  
  392. ge_pick()
  393. {
  394.   int segno;
  395.   int pickid;
  396.  
  397.   /* flush previous input */
  398.   ge_flush();
  399.  
  400.   /* pick segment */
  401.   await_pick(1000000000, 1, &segno, &pickid);
  402.   return(segno);
  403.  
  404. } /* ge_pick */
  405.  
  406. /*****************************************************************************
  407.  
  408.     ge_draw will update the display of a segment on the view surface.
  409.   If the segment is marked deleted, the segment will be make invisible on
  410.   the display.  If the segment has been drawn, the old image on the view
  411.   surface will be erased.
  412.  
  413.     To minimize the time between the old image is erased and the new
  414.   image is drawn, the new image is first drawn in an invisible
  415.   temporary segment.  The old image is then deleted and the new
  416.   temporary segment renamed to be the segment.
  417.  
  418.   Input
  419.     segno - number of segment to draw
  420.  
  421. *****************************************************************************/
  422.  
  423. /* map graphedit linestyle to SunCore linestyle */
  424. static int linestyle_menu[]=
  425. {SOLID,DOTTED,DASHED,DOTDASHED};
  426.  
  427. /* map graphedit font to SunCore font */
  428. static int font_menu[]=
  429. {STICK,ROMAN,GREEK,SCRIPT,OLDENGLISH};
  430.  
  431. /* table to adjust width of font in SunCore so that they will have
  432.    proportional width with fonts in PostScript */
  433. static float charwidthfactor[] = { 1.28, 1.54, 1.42, 1.49, 1.48 };
  434. static int segmentfont, segmentcharsize;
  435.  
  436. /* ge_setchar will set the character size according to the graphedit
  437.    character size and font */
  438. #define ge_setchar(size,font) set_charsize((size)/charwidthfactor[(font)],(size)/1.5)
  439.  
  440. ge_draw(segno)
  441. int segno;
  442. {
  443.   struct list *seginfo, *ge_display_list();
  444.   struct list_item *ptr;
  445.   static struct list_item closeinstr={GE_CLOSE, 0.,0.,NULL};
  446.   float tx,ty;
  447.  
  448.   /* abort if the display list of the segment cannot be found or is
  449.      empty */
  450.   if ( !((seginfo=ge_display_list(segno)) &&
  451.          (ptr=seginfo->d_list)) )
  452.     return;
  453.  
  454.   /* set the initial attributes of the segment */
  455.   segmentfont = seginfo->attr.font;
  456.   segmentcharsize = seginfo->attr.charsize;
  457.   set_fill_index(colortable[clrmap[seginfo->attr.color]]);
  458.   set_linestyle(linestyle_menu[seginfo->attr.linestyle]);
  459.   set_linewidth((float)seginfo->attr.linewidth/5.);
  460.   ge_setchar((float)seginfo->attr.charsize,seginfo->attr.font);
  461.   set_font(font_menu[seginfo->attr.font]);
  462.  
  463.   /* create an invisible temporary segment*/
  464.   create_retained_segment(GE_TMPSEG);
  465.   set_segment_visibility(GE_TMPSEG,0);
  466.  
  467.   /* scan the display list of the segment to draw the image */
  468.   ptr=ptr->next;
  469.   do {
  470.     ge_exec(ptr);
  471.     ptr=ptr->next;
  472.   } while ( ptr != seginfo->d_list->next );
  473.  
  474.   /* close the segment */
  475.   ge_exec(&closeinstr);
  476.  
  477.   /* make user segments detectable and sample segment undetectable */
  478.   if ( segno >= GE_MIN_SEG ) {
  479.     set_segment_detectability(GE_TMPSEG, segno);
  480.   }
  481.   else {
  482.     set_segment_detectability(GE_TMPSEG, 0);
  483.   }
  484.  
  485.   /* close the temporary segment */
  486.   close_retained_segment(GE_TMPSEG);
  487.  
  488.   /* set the transformation of the segment */
  489.   map_world_to_ndc_2(seginfo->attr.tx, seginfo->attr.ty, &tx, &ty);
  490.   set_segment_image_transformation_2(GE_TMPSEG,
  491.     seginfo->attr.sx, seginfo->attr.sy,
  492.     seginfo->attr.ang, tx, ty);
  493.  
  494.   /* delete the old image if the segment has been drawn before */
  495.   if ( seginfo->attr.drawn )
  496.     delete_retained_segment(segno);
  497.  
  498.   /* make the temporary segment visible */
  499.   set_segment_visibility(GE_TMPSEG,!seginfo->attr.deleted);
  500.  
  501.   /* rename the temporary segment to be the segment */
  502.   rename_retained_segment(GE_TMPSEG, segno);
  503.  
  504.   seginfo->attr.drawn=1;
  505.  
  506. } /* ge_draw */
  507.  
  508. /*****************************************************************************
  509.  
  510.     ge_draw_ellipse will draw a ellipse will a number of lines.  The equation
  511.   of the ellipse is
  512.  
  513.       2      2
  514.      x      y
  515.     ---  + ---  = 1
  516.       2      2
  517.      a      b
  518.  
  519.   Input
  520.     a, b - parameter in equation
  521.     fill - how the ellipse should be filled/bordered
  522.  
  523. *****************************************************************************/
  524.  
  525. #define LINEPERCIRCLE 20 /* number of lines to form a circle */
  526.  
  527. ge_draw_ellipse(a,b,fill)
  528. float a,b;
  529. int fill;
  530. {
  531.   float i;
  532.   float oldsin, oldcos;
  533.   float tmpsin, tmpcos;
  534.   float intv;
  535.   float ang;
  536.   int count;
  537.   float xbuff[LINEPERCIRCLE+1], ybuff[LINEPERCIRCLE+1];
  538.  
  539.   intv=2.*PI/LINEPERCIRCLE;
  540.   ang=0.;
  541.   count=1;
  542.  
  543.   xbuff[0]=a*(oldcos=cos((double)ang));
  544.   ybuff[0]=b*(oldsin=sin((double)ang));
  545.  
  546.   for (ang=intv; !(ang>(2.1*PI)); ang+=intv) {
  547.     xbuff[count]=a*(-oldcos+(tmpcos=cos((double)ang)));
  548.     ybuff[count++]=b*(-oldsin+(tmpsin=sin((double)ang)));
  549.     oldcos=tmpcos;  oldsin=tmpsin;
  550.   } /* for */
  551.  
  552.   if ( (fill==GE_FILLONLY) || (fill==GE_FILLBORDER) ) {
  553.     /* fill region */
  554.     polygon_rel_2(xbuff,ybuff,count);
  555.     move_rel_2(-xbuff[0], -ybuff[0]);
  556.   } /* if */
  557.  
  558.   if ( (fill==GE_BORDERONLY) || (fill==GE_FILLBORDER) ) {
  559.     /* draw border */
  560.     move_rel_2(xbuff[0],ybuff[0]);
  561.     polyline_rel_2(&(xbuff[1]),&(ybuff[1]),count-1);
  562.   } /* if */
  563.  
  564. } /* ge_draw_ellipse */
  565.  
  566. /*****************************************************************************
  567.  
  568.     ge_draw_arc will draw an arc with center at current point, from ang1
  569.   to ang2 with radius radius.
  570.  
  571.   Input
  572.     ang1 - from angle, 0 <= ang1 <= 2PI
  573.     ang2 - to angle, 0 <= ang2 <= 2PI
  574.     radius - radius of arc
  575.  
  576. *****************************************************************************/
  577.  
  578. ge_draw_arc(ang1,ang2,radius)
  579. float ang1,ang2,radius;
  580. {
  581.   float intv, ang;
  582.   float oldsin, oldcos, tmpsin, tmpcos;
  583.   int count;
  584.   float xbuff[LINEPERCIRCLE+1], ybuff[LINEPERCIRCLE+1];
  585.  
  586.   /* ensure that ang1 < ang2 */
  587.   if ( ang1 > ang2 ) {
  588.     ang1 -= 2*PI;
  589.   }
  590.  
  591.   /* determine the interval */
  592.   intv=2.*PI/LINEPERCIRCLE;
  593.   if ((ang2-ang1) < (3*intv) ) {
  594.     /* a minimum of three lines are drawn for the arc */
  595.     intv = (ang2-ang1)/3;
  596.   }
  597.  
  598.   /* the first point */
  599.   ang=ang1;
  600.   count=1;
  601.   xbuff[0]=radius*(oldcos=cos((double)ang));
  602.   ybuff[0]=radius*(oldsin=sin((double)ang));
  603.  
  604.   /* determine the following points */
  605.   for (ang += intv; ang < ang2; ang+=intv) {
  606.     xbuff[count]=radius*(-oldcos+(tmpcos=cos((double)ang)));
  607.     ybuff[count++]=radius*(-oldsin+(tmpsin=sin((double)ang)));
  608.     oldcos=tmpcos;  oldsin=tmpsin;
  609.   }
  610.  
  611.   /* the last point */
  612.   xbuff[count]=radius*(-oldcos+(cos((double)ang2)));
  613.   ybuff[count++]=radius*(-oldsin+(sin((double)ang2)));
  614.  
  615.   /* draw the arc */
  616.   move_rel_2(xbuff[0],ybuff[0]);
  617.   polyline_rel_2(&(xbuff[1]),&(ybuff[1]),count-1);
  618.  
  619. } /* ge_draw_arc */
  620.  
  621. /*****************************************************************************
  622.  
  623.     ge_exec will execute an instruction on a display list.
  624.  
  625.   Input
  626.     ptr - pointer to the instruction
  627.  
  628. *****************************************************************************/
  629.  
  630. ge_exec(ptr)
  631. struct list_item *ptr;
  632. {
  633.   static float xbuff[512], ybuff[512];
  634.   static int lastinstr=0;
  635.   static int n=0;
  636.   static int fill=0;
  637.  
  638.   /* execute last polyline/polygon instruction if instruction indicates
  639.      end of the last instruction */
  640.   if ( lastinstr && ptr->instr != GE_CONT ) {
  641.     switch ( lastinstr ) {
  642.       case GE_POLYLINE :
  643.         polyline_abs_2(xbuff,ybuff,n);
  644.         break;
  645.  
  646.       case GE_POLYGON : {
  647.  
  648.         /* do not draw if there are less than 3 points */
  649.         if ( n < 3 ) {
  650.           fill=0;
  651.           break;
  652.         }
  653.  
  654.         if ( (fill==GE_FILLONLY) || (fill==GE_FILLBORDER) ) {
  655.           /* fill region */
  656.           polygon_abs_2(xbuff,ybuff,n);
  657.         }
  658.  
  659.         if ( (fill==GE_BORDERONLY) || (fill==GE_FILLBORDER) ) {
  660.           /* draw border */
  661.           move_abs_2(xbuff[n-1],ybuff[n-1]);
  662.           polyline_abs_2(xbuff,ybuff,n);
  663.         }
  664.  
  665.         fill=0;
  666.         break;
  667.       } /* GE_POLYGON */
  668.  
  669.       default: ;
  670.     } /* switch */
  671.  
  672.     lastinstr = n = 0;
  673.  
  674.   } /* if */
  675.  
  676.   /* execute new instruction */
  677.   switch ( ptr->instr) {
  678.  
  679.     /* instructions with single coordinate */
  680.     case GE_MOVE:
  681.       move_abs_2(ptr->x,ptr->y);
  682.       break;
  683.  
  684.     case GE_LINE:
  685.       line_abs_2(ptr->x,ptr->y);
  686.       break;
  687.  
  688.     case GE_PLOT:
  689.       move_abs_2(ptr->x,ptr->y);
  690.       line_rel_2(0.,0.);
  691.       break;
  692.  
  693.     case GE_TEXT:
  694.       text((char *)((int)ptr->x));
  695.       break;
  696.  
  697.     case GE_FILL:
  698.       fill=(int)ptr->x;
  699.       break;
  700.  
  701.     /* instruction with two or more coordinates */
  702.     case GE_POLYLINE:
  703.     case GE_POLYGON:
  704.       lastinstr=ptr->instr; /* store instruction */
  705.  
  706.     case GE_CONT:
  707.       /* save coordinate of polyline/polygon */
  708.       xbuff[n] = ptr->x;
  709.       ybuff[n++]= ptr->y;
  710.       break;
  711.  
  712.     case GE_CIRCLE:
  713.       ge_draw_ellipse(ptr->x,ptr->x,fill);
  714.       fill = 0;
  715.       break;
  716.  
  717.     case GE_ELLIPSE:
  718.       ge_draw_ellipse(ptr->x,ptr->y,fill);
  719.       fill = 0;
  720.       break;
  721.  
  722.     case GE_ARC:
  723.       /* save the angles */
  724.       xbuff[0]=ptr->x;
  725.       ybuff[0]=ptr->y;
  726.       break;
  727.  
  728.     case GE_ARCEXT:
  729.       ge_draw_arc(xbuff[0],ybuff[0],ptr->x);
  730.       break;
  731.  
  732.     /* change the attributes of the segment */
  733.     case GE_SETCOLOR:
  734.       set_fill_index(colortable[clrmap[(int)ptr->x]]);
  735.       break;
  736.  
  737.     case GE_SETTYPELINE:
  738.       set_linestyle(linestyle_menu[(int)ptr->x]);
  739.       break;
  740.  
  741.     case GE_SETLINEWIDTH:
  742.       set_linewidth(ptr->x/5.);
  743.       break;
  744.  
  745.     case GE_SETCHARSIZE:
  746.       ge_setchar(ptr->x,segmentfont);
  747.       segmentcharsize = (int) ptr->x;
  748.       break;
  749.  
  750.     case GE_SETFONT:
  751.       set_font(font_menu[(int)ptr->x]);
  752.       segmentfont = (int)ptr->x;
  753.       ge_setchar(segmentcharsize, segmentfont);
  754.       break;
  755.  
  756.     case GE_CLOSE:
  757.       break;
  758.  
  759.     default :
  760.       /* check that all instructions are handled properly */
  761.       fprintf(stderr,
  762.               "Internal Error-Action for instruction %d missing.\n",
  763.               ptr->instr);
  764.       break;
  765.  
  766.   } /* switch */
  767.  
  768. } /* ge_exec */
  769.  
  770. /*****************************************************************************
  771.  
  772.     ge_redisplay will redraw the segment will any new transformation.
  773.  
  774. *****************************************************************************/
  775.  
  776. ge_redisplay(seginfo)
  777. struct list *seginfo;
  778. {
  779.   float tx, ty;
  780.  
  781.   /* translation should be in ndc */
  782.   map_world_to_ndc_2(seginfo->attr.tx, seginfo->attr.ty, &tx, &ty);
  783.   /* will redraw the segment */
  784.   set_segment_image_transformation_2(seginfo->segno,
  785.                                seginfo->attr.sx, seginfo->attr.sy,
  786.                                seginfo->attr.ang,tx,ty);
  787.  
  788. } /* ge_redisplay */
  789.  
  790. /*****************************************************************************
  791.  
  792.     core_write will write the pixrect image of a region on the view surface
  793.   as a rasterfile on file.
  794.  
  795.   Input
  796.     file - opened stream to write to
  797.     xmin, ymin - coordinate of a corner of region in world coordinate
  798.     xmax, ymax - coordinate of diagonal corner of region in world coordinate
  799.  
  800. *****************************************************************************/
  801.  
  802. core_write(file, xmin, ymin, xmax, ymax)
  803. FILE *file;
  804. float xmin, ymin, xmax, ymax;
  805. {
  806.   struct suncore_raster raster;
  807.   float nx1, ny1, nx2, ny2, tmp;
  808.  
  809.   /* empty colormap structure for raster_to_file */
  810.   static struct {
  811.     int type;
  812.     int nbytes;
  813.     char *data;
  814.   } color_map = { 0, 0, 0 };
  815.  
  816.   /* convert coordinates to ndc coordinates */
  817.   map_world_to_ndc_2(xmin, ymin, &nx1, &ny1);
  818.   map_world_to_ndc_2(xmax, ymax, &nx2, &ny2);
  819.  
  820.   /* make (nx1,ny1) the lower left corner and (nx2,ny2) the upper right
  821.      corner */
  822.   if ( nx2 < nx1 ) {
  823.     tmp = nx1;
  824.     nx1 = nx2;
  825.     nx2 = tmp;
  826.   }
  827.   if ( ny2 < ny1 ) {
  828.     tmp = ny1;
  829.     ny1 = ny2;
  830.     ny2 = tmp;
  831.   }
  832.  
  833.   /* allocate memory for the pixrect image */
  834.   size_raster(our_surface, nx1, nx2, ny1, ny2, &raster);
  835.   allocate_raster(&raster);
  836.  
  837.   /* get the pixrect image */
  838.   get_raster(our_surface, nx1, nx2, ny1, ny2, 0, 0, &raster);
  839.  
  840.   /* write pixrect image as raster file */
  841.   raster_to_file(&raster, &color_map, file->_file, 1);
  842.  
  843.   /* free memory */
  844.   free_raster(&raster);
  845.  
  846. } /* core_write */
  847.  
  848. /*****************************************************************************
  849.  
  850.     ge_refresh will refresh the view surface.
  851.  
  852. *****************************************************************************/
  853.  
  854. ge_refresh()
  855. {
  856.  
  857.   new_frame();
  858.  
  859. } /* ge_refresh */
  860. @//E*O*F core.c//
  861. chmod u=r,g=r,o=r core.c
  862.  
  863. echo Inspecting for damage in transit...
  864. temp=/tmp/shar$$; dtemp=/tmp/.shar$$
  865. trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
  866. cat > $temp <<\!!!
  867.      843    2410   23387 core.c
  868. !!!
  869. wc  core.c | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
  870. if [ -s $dtemp ]
  871. then echo "Ouch [diff of wc output]:" ; cat $dtemp
  872. else echo "No problems found."
  873. fi
  874. exit 0
  875.  
  876.